From 8456d2ae4daf0f567554f38a8d245278b0054ec4 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 29 Jan 2016 23:47:16 +0300 Subject: [PATCH] metadata: change resolve serialization --- src/cargo/ops/cargo_output_metadata.rs | 47 ++++++++++++++++++++++---- tests/test_cargo_metadata.rs | 43 ++++++++++------------- 2 files changed, 59 insertions(+), 31 deletions(-) diff --git a/src/cargo/ops/cargo_output_metadata.rs b/src/cargo/ops/cargo_output_metadata.rs index 33be1857f..a5ebdc100 100644 --- a/src/cargo/ops/cargo_output_metadata.rs +++ b/src/cargo/ops/cargo_output_metadata.rs @@ -1,7 +1,9 @@ use std::path::Path; +use rustc_serialize::{Encodable, Encoder}; + use core::resolver::Resolve; -use core::{Source, Package}; +use core::{Source, Package, PackageId}; use ops; use sources::PathSource; use util::config::Config; @@ -19,9 +21,7 @@ pub struct OutputMetadataOptions<'a> { /// Loads the manifest, resolves the dependencies of the project to the concrete /// used versions - considering overrides - and writes all dependencies in a JSON /// format to stdout. -pub fn output_metadata<'a>(opt: OutputMetadataOptions, - config: &'a Config) - -> CargoResult { +pub fn output_metadata(opt: OutputMetadataOptions, config: &Config) -> CargoResult { let deps = try!(resolve_dependencies(opt.manifest_path, config, opt.features, @@ -31,7 +31,7 @@ pub fn output_metadata<'a>(opt: OutputMetadataOptions, assert_eq!(opt.version, VERSION); Ok(ExportInfo { packages: packages, - resolve: resolve, + resolve: MetadataResolve(resolve), version: VERSION, }) } @@ -39,10 +39,45 @@ pub fn output_metadata<'a>(opt: OutputMetadataOptions, #[derive(RustcEncodable)] pub struct ExportInfo { packages: Vec, - resolve: Resolve, + resolve: MetadataResolve, version: u32, } +/// Newtype wrapper to provide a custom `Encodable` implementation. +/// The one from lockfile does not fit because it uses a non-standard +/// format for `PackageId`s +struct MetadataResolve(Resolve); + +impl Encodable for MetadataResolve { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { + #[derive(RustcEncodable)] + struct EncodableResolve<'a> { + root: &'a PackageId, + nodes: Vec>, + } + + #[derive(RustcEncodable)] + struct Node<'a> { + id: &'a PackageId, + dependencies: Vec<&'a PackageId>, + } + + let resolve = &self.0; + let encodable = EncodableResolve { + root: resolve.root(), + nodes: resolve.iter().map(|id| { + Node { + id: id, + dependencies: resolve.deps(id) + .map(|it| it.collect()) + .unwrap_or(Vec::new()), + } + }).collect(), + }; + + encodable.encode(s) + } +} /// Loads the manifest and resolves the dependencies of the project to the /// concrete used versions. Afterwards available overrides of dependencies are applied. diff --git a/tests/test_cargo_metadata.rs b/tests/test_cargo_metadata.rs index 09afbb2fc..e62cb186f 100644 --- a/tests/test_cargo_metadata.rs +++ b/tests/test_cargo_metadata.rs @@ -1,4 +1,4 @@ -use hamcrest::{assert_that, existing_file}; +use hamcrest::assert_that; use support::registry::Package; use support::{project, execs, basic_bin_manifest}; @@ -32,14 +32,13 @@ test!(cargo_metadata_simple { } ], "resolve": { - "package": [], - "root": { - "name": "foo", - "version": "0.5.0", - "source": null, - "dependencies" : [] - }, - "metadata": null + "nodes": [ + { + "dependencies": [], + "id": "foo 0.5.0 (path+file:[..]foo)" + } + ], + "root": "foo 0.5.0 (path+file:[..]foo)" }, "version": 1 }"#)); @@ -146,31 +145,25 @@ test!(cargo_metadata_with_deps { } ], "resolve": { - "metadata": null, - "package": [ + "nodes": [ + { + "dependencies": [ + "bar 0.0.1 (registry+file:[..])" + ], + "id": "foo 0.5.0 (path+file:[..]foo)" + }, { "dependencies": [ "baz 0.0.1 (registry+file:[..])" ], - "name": "bar", - "source": "registry+file:[..]", - "version": "0.0.1" + "id": "bar 0.0.1 (registry+file:[..])" }, { "dependencies": [], - "name": "baz", - "source": "registry+file:[..]", - "version": "0.0.1" + "id": "baz 0.0.1 (registry+file:[..])" } ], - "root": { - "dependencies": [ - "bar 0.0.1 (registry+file:[..])" - ], - "name": "foo", - "source": null, - "version": "0.5.0" - } + "root": "foo 0.5.0 (path+file:[..]foo)" }, "version": 1 }"#)); -- 2.30.2